home *** CD-ROM | disk | FTP | other *** search
- /*======================================================================
- * File Name: alloc.c *
- * Purpose : memory allocation routines *
- * Allocation routines. changed from K&R to the use of TURBO C++ offered *
- * routines. This is probably not a very portable solution, but it gives *
- * at least some relief when used under (MS)DOS. *
- * *
- * Date Name Description *
- * ---- ---- ----------- *
- * 04-apr-1991 AA6HM/DK5DC initial implementation *
- * 09-apr-1991 AA6HM/DK5DC added memory record *
- * 11-apr-1991 AA6HM/DK5DC added crashdump facility *
- * 14-apr-1991 AA6HM/DK5DC changed crashdump to ask Turbo C++ via *
- * heapchecknode(),if he agrrees to dump and *
- * exit because of a corrupted node *
- *=======================================================================*/
- #define __ALLOC_C 1
-
- #include <stdio.h>
- #include <dos.h>
- #include <alloc.h>
- #include <fcntl.h> /* for filemodes DK5DC */
- #include <io.h> /* for creattemp() */
- #include <ctype.h> /* for isprint */
- #include <conio.h>
- #include "global.h"
- #include "proc.h"
- #include "cmdparse.h"
- #include "mbuf.h"
- #include "session.h"
- #include "files.h"
- #include "commands.h" /* for doexit() */
-
- #ifdef __CPLUSPLUS
- #define Free 0
- #define Used 1
- #define Over 2
- #endif
- #define MDDEBUG
-
- static unsigned long Intalloc; /* Calls to malloc with ints disabled */
- static unsigned long Memfail; /* Count of allocation failures */
- static unsigned long Allocs; /* Total allocations */
- static unsigned long Frees; /* Total frees */
- static unsigned long Invalid; /* Total calls to free with garbage arg*/
- static unsigned long Intfree; /* Calls to free with ints disabled */
- static unsigned long Overuse; /* tot calls to free with overused arg */
-
- static int Memwait = 0; /* Number of tasks waiting for memory */
- static int Memcold = 0; /* controls rebooting when memory goes low */
-
- #ifdef MDEBUG
- static unsigned long Sizes[16];
- static FILE *rfp = 0; /* points to memrecord */
- static int rflag = 0;
- #endif
- extern int Nibufs;
- extern unsigned Ibufsize;
- extern int setuns __ARGS((unsigned *var,char *label,int argc,char *argv[]));
-
-
- #ifdef MDEBUG
- # define PARA 16
- # define UNIT 8
- # define ALLOC "\xAA" /* marker for alloc */
- # define FREE "\x55" /* marker for free */
-
- /*----------------------------------------------------------------------*
- * template to access inserted debug info *
- *-----------------------------------------------------------------------*/
- typedef struct {
- unsigned line;
- char file[10];
- }Hd;
-
- #else
-
- /*----------------------------------------------------------------------*
- * template to access Turbo C++'s memory linkages
- *-----------------------------------------------------------------------*/
- typedef struct {
- unsigned np; /* noOfParagraphs in block */
- unsigned seg; /* used: link to previous segment */
- unsigned backseg,forseg; /* free freelist linkage */
- }Id;
-
- #define Hd char
- #endif
-
- /*----------------------------------------------------------------------*
- * the two variables below are maintained by C++ to mark the start and *
- * end of the used heap *
- *-----------------------------------------------------------------------*/
- #ifdef __CPLUSPLUS
- extern unsigned far __first;
- extern unsigned far __last;
- extern unsigned far __rover;
- // DL8YQ
- static Hd huge * near checkheap __ARGS((void));
- #endif
-
- #ifdef MDEBUG
- static int dump(Hd huge *cret);
- #endif
- /*-----------------------------------------------------------------------*
- * Set the C++ roving memory pointer to the first free block *
- *------------------------------------------------------------------------*/
- static void near
- _setrover (void)
- {
- struct heapinfo hp;
-
- hp.ptr = 0;
- while(heapwalk(&hp) != _HEAPEND) {
- if(hp.in_use == 0){
- __rover = FP_SEG(hp.ptr);
- break;
- }
- }
- }
-
- /*----------------------------------------------------------------------*
- * Allocate block of 'nb' bytes *
- *-----------------------------------------------------------------------*/
- #ifdef MDEBUG
- void *
- mxalloc(char *file,unsigned line,unsigned nb)
- #else
- void *
- mxalloc(unsigned nb)
- #endif
- {
- register Hd *node;
-
-
- #ifdef MDEBUG
- unsigned foo;
- int i;
- struct time stime;
- #endif
-
- if(!istate())
- Intalloc++;
- /*-------------------------------------------------------------------*
- * If memory is below Memthresh, reboot the system. This seemes to be *
- * a more secure way to prevent garbage and 'unexpected modes'. *
- *--------------------------------------------------------------------*/
- if((availmem() < (Memthresh + nb))) { /* !! TEST !! */
- if(Memcold) {
- void (*foo) __ARGS((void));
-
- foo = MK_FP(0xffff,0); /* FFFF:0000 is hardware reset vector */
- (*foo)(); /* no return */
- } else {
- doexit(252,0,0);
- }
- }
- if(nb == 0)
- return NULL;
-
- _setrover();
- #ifdef MDEBUG
- /*-------------------------------------------------------------------*
- * Record the size of this request *
- *--------------------------------------------------------------------*/
- foo = nb;
- for(i=0;i<16;i++){
- if(foo >= 32768L)
- break;
- foo <<= 1;
- }
- Sizes[15-i]++;
-
- /*-------------------------------------------------------------------*
- * the calloc() is merely a circumvention, cause I'm unable to find *
- * ALL the uninitialized 'next ptr's' in that whole crop of NOS *
- * functions. calloc() makes sure to get (zero) initialized memory *
- *--------------------------------------------------------------------*/
- #ifdef LARGEDATA
- if ((node = farcalloc(1,nb+PARA))!=0) {
- #else
- if ((node = calloc(1,nb+PARA))!=0) {
- #endif
- /*----------------------------------------------------------------*
- * insert the line/file info passed when MDEBUG is on *
- *-----------------------------------------------------------------*/
- sprintf(node->file,"%.8s",file);
- node->line = line;
- /*----------------------------------------------------------------*
- * if recording is on, build a record and write it into the file *
- *-----------------------------------------------------------------*/
- if (rflag) {
- /*-------------------------------------------------------------*
- * use dostime(), cause it calculates much faster than time() *
- * and has a granularity of 10 milliseconds *
- *--------------------------------------------------------------*/
- unsigned seg;
- gettime(&stime);
- fwrite(ALLOC,1,1,rfp); /* write the marker */
- fwrite(&stime,sizeof(struct time),1,rfp);
- seg = FP_SEG((char *)node-4); /* alloce'd segment */
- fwrite(&seg,sizeof(unsigned),1,rfp);
- fwrite(((char *)node-4),PARA,1,rfp);
- seg = line;
- fwrite(&seg,sizeof(unsigned),1,rfp);
- fwrite(file,10,1,rfp);
- }
- Allocs++;
- return(node+1);
- }
- #else
- #ifdef LARGEDATA
- if ((node = farcalloc(1,nb)) != 0) {
- #else
- if ((node = calloc(1,nb)) != 0) {
- #endif
- Allocs++;
- return(node);
- }
- #endif
-
- Memfail++;
- return(NULL);
- }
-
- /*----------------------------------------------------------------------*
- * Put memory block back on heap *
- *-----------------------------------------------------------------------*/
- #ifdef MDEBUG
- void
- xfree(char *file,unsigned line,void *b)
- #else
- void
- xfree(void *b)
- #endif
- {
- #ifdef __CPLUSPLUS
- Hd huge *cret;
- #endif
- #ifdef MDEBUG
- Hd huge *blk;
- struct time stime;
- #endif
-
- if(b == NULL)
- return; /* Required by ANSI */
-
- if(!istate())
- Intfree++;
-
- #ifdef MDEBUG
- blk = (Hd *)b - 1;
- #endif
- #ifdef __CPLUSPLUS
- /*-------------------------------------------------------------------*
- * make the audit check
- *--------------------------------------------------------------------*/
- if((cret = checkheap()) != 0) {
- #ifdef MDEBUG
- tprintf("free: WARNING! corrupted Node (%Fp) %10.10s %05u proc %s\n",
- cret,cret->file,cret->line,Curproc->name);
- dump(cret); /* POOF!!!!! */
- #else
- printf("\nfree(): corrupted Node (%Fp) proc %s\n\n",
- cret,Curproc->name);
- #endif
- exit(255);
- }
- #endif
- #ifdef MDEBUG
- else if (rflag) {
- unsigned seg;
- gettime(&stime);
- fwrite(FREE,1,1,rfp);
- fwrite(&stime,sizeof(struct time),1,rfp);
- seg = FP_SEG((char *)blk-4);
- fwrite(&seg,sizeof(unsigned),1,rfp);
- fwrite(((char *)blk-4),PARA,1,rfp);
- }
- #endif
-
- #ifdef MDEBUG
- free((void *)blk);
- #else
- free((void *)b);
- #endif
- Frees++;
-
- if(Memwait != 0)
- psignal(&Memwait,0);
-
- }
-
- #ifdef MDEBUG
- /*----------------------------------------------------------------------*
- * Dump the memory in case of an error detected by checkheap and exit.. *
- * low level routines are used..... *
- *-----------------------------------------------------------------------*/
- static int
- dump(Hd huge *cret)
- {
- int fd,seg,fmode;
- char huge *para;
- extern struct proc *Curproc; /* Currently running process */
- extern struct proc *Rdytab; /* Processes ready to run (not including curproc)*/
- extern struct proc *Waittab[]; /* Waiting process list */
- extern struct proc *Susptab; /* Suspended processes */
- extern struct timer *Timers;
- struct timer *tp;
- int i_state;
- char path[128];
-
- if(getenv("HOME") != NULL) {
- strcpy(path,getenv("HOME"));
- strcat(path,"\\");
- } else
- strcpy(path,"\\");
-
- fmode = _fmode; /* preserve filemode */
- _fmode = O_BINARY;
-
- if ((fd = creattemp(path,0))<0) {
- _fmode = fmode;
- return(-1);
- } else {
- i_state = dirps();
- tprintf("Memory dump started...file = %s\n",path);
- write(fd,&__first,2); /* write __first ptr */
- write(fd,&__last,2); /* write __last ptr */
- write(fd,&cret,4); /* save error position */
- write(fd,(char *)cret-4,16); /* save suspected header */
- /*----------------------------------------------------------------*
- * save processing queue ptrs... *
- *-----------------------------------------------------------------*/
- write(fd,&Curproc,sizeof(struct proc *));
- write(fd,&Rdytab,sizeof(struct proc *));
- write(fd,&Susptab,sizeof(struct proc *));
- write(fd,&Waittab,16*sizeof(struct proc *));
- /*----------------------------------------------------------------*
- * save the Timerchain..... *
- *-----------------------------------------------------------------*/
- for (tp = Timers; tp; tp = tp->next)
- write(fd,tp,sizeof(struct timer ));
- /*----------------------------------------------------------------*
- * save session control blocks *
- *-----------------------------------------------------------------*/
- seg = NSESSIONS;
- write(fd,&seg,sizeof(int));
- write(fd,Sessions,sizeof(struct session)*Nsessions);
- /*----------------------------------------------------------------*
- * save the file descriptors, at least the first 16... *
- *-----------------------------------------------------------------*/
- write(fd,(char *)&_streams,16*sizeof(FILE));
- /*----------------------------------------------------------------*
- * now dump the whole heap... maybe expanded to whole system *
- * sessions,tcb's etc to get a snapshot of the system *
- *-----------------------------------------------------------------*/
- for (seg = __first; seg < __last; seg++) {
- para = MK_FP(seg,0);
- write(fd,(void *)para,PARA);
- }
- close(fd);
- }
- restore(i_state);
- _fmode = fmode;
- return(0);
- }
- #endif
-
- /*----------------------------------------------------------------------*
- * This is a very rough check routine. As I dive into the code *
- * the routine might be streamlined DK5DC *
- * As far as I could find the facts, the C++ memory links are built as *
- * follows: *
- * 1. Memory is ALWAYS allocated on a paragraph (16 Byte) Basis *
- * TC++ ALWAYS returns a address in the form *
- * Segment:0004. The first four bytes in the first paragraph are*
- * used for size and link informations. The first two bytes *
- * contain the size of the block in paragraphs *
- * The remaining two bytes contain a segment address pointing *
- * to the previous (allocated block) or to (^self). *
- * 2. A FREE entry uses two more byte pairs for header information *
- * (This caused some bad NOS crashes when some code was running*
- * along a linked list, a block was freed, the 'next'pointer *
- * was defined as the first member of the structure and NOS *
- * tried to access that ptr AFTER freeing the block) *
- * Anyway, those two pairs of code contain a backward *
- * and forward pointer to its free neighbours. *
- *-----------------------------------------------------------------------*/
- #ifdef __CPLUSPLUS
- static Hd huge * near
- checkheap(void)
- {
- unsigned prev;
- unsigned last;
- unsigned run;
- Id huge *rp;
-
- last =__last;
- run = prev =__first;
- rp = 0;
- /*-------------------------------------------------------------------*
- * scan the heap *
- *--------------------------------------------------------------------*/
- while (run<last) {
- rp = MK_FP(run,0);
- /*----------------------------------------------------------------*
- * make the test *
- *-----------------------------------------------------------------*/
- if (rp->seg != NULL && rp->seg != prev) {
- rp = MK_FP(run,4);
- /*-------------------------------------------------------------*
- * before getting nasty, ask C++ to check again... *
- *--------------------------------------------------------------*/
- if(heapcheck() < 0) {
- rp = MK_FP(prev,0);
- return((Hd huge *)((char *)rp+4));
- }
- }
- prev = run;
- run += rp->np;
- }
- return(0);
- }
- #endif
-
- /* new DL8YQ */
- /*----------------------------------------------------------------------*
- * Version of malloc() that waits if necessary for memory to become available *
- *-----------------------------------------------------------------------*/
- #ifdef MDEBUG
- void *
- mxallocw(char *file,unsigned line,unsigned nb)
- #else
- void *
- mxallocw(unsigned nb)
- #endif
- {
- register char *cp;
-
- semwait(&Memwait,1);
- cp=mxalloc(nb);
- semrel(&Memwait);
- return cp;
- /*
- while ((cp = mxalloc(nb)) == NULL){
- Memwait++;
- pwait(&Memwait);
- Memwait--;
- }
- return cp;
- */
- }
-
-
- /*----------------------------------------------------------------------*
- * Allocate block of cleared memory *
- *-----------------------------------------------------------------------*/
- #ifdef MDEBUG
-
- void *
- cxalloc(char *file,unsigned line,unsigned nelem,unsigned size)
- #else
- void *
- cxalloc(unsigned nelem,unsigned size)
- #endif
- {
- #ifdef MDEBUG
- char *cp = mxalloc(file,line,(nelem * size));
- #else
- register char *cp = calloc(1,nelem * size);
- #endif
-
- return cp;
- }
-
- /*----------------------------------------------------------------------*
- * Version of calloc that waits if necessary for memory to become available *
- *-----------------------------------------------------------------------*/
- #ifdef MDEBUG
- void *
- cxallocw(char *file,unsigned line,unsigned nelem,unsigned size)
- #else
- void *
- cxallocw(unsigned nelem,unsigned size)
- #endif
- {
- register char *cp;
-
- semwait(&Memwait,1);
- cp = mxalloc(nelem * size);
- semrel(&Memwait);
- return cp;
- }
-
- /*----------------------------------------------------------------------*
- * Copy a string to a malloc'ed buffer. Turbo C has this one in its *
- * library, but it doesn't call mallocw() and can therefore return NULL. *
- * NOS uses of strdup() generally don't check for NULL, so they need this*
- * one. *
- * *
- * Changed the name to strxdup and added the file/line pair insertion. *
- * Otherwise only the malloc() would be recorded, which is always inside *
- * strxdup() and not the strdup location itself. *
- *-----------------------------------------------------------------------*/
- #ifdef MDEBUG
- char *
- strxdup(char *file,unsigned line,const char *s)
- #else
- char *
- strxdup(const char *s)
- #endif
- {
- char *out;
- int len;
-
- if(s == NULLCHAR)
- return NULLCHAR;
-
- len = strlen(s);
- #ifdef MDEBUG
- out = mxallocw(file,line,len+1);
- #else
- out = mxallocw(len+1);
- #endif
- /* This is probably a tad faster than strcpy, since we know the len */
- memcpy(out,s,len);
- out[len] = '\0';
- return out;
- }
-
- /*----------------------------------------------------------------------*
- * Return available memory on our heap plus available system memory *
- *-----------------------------------------------------------------------*/
- unsigned long availmem()
- {
- return (unsigned long)coreleft();
- }
-
- /*----------------------------------------------------------------------*
- *-----------------------------------------------------------------------*/
- #ifdef MDEBUG
- int
- openmemrec(char *name)
- {
- if ((rfp = fopen(name,"w+b",0,1)) == NULLFILE) {
- tprintf("Error opening file: %s\n",name);
- return(-1);
- }
- fprintf(rfp,
- "THIS FILE CONTAINS BINARY DATA... use ANALMEM \n\r\x1a");
- tprintf("Recording memory allocs to %s\n",name);
- rflag = 1;
- return(0);
- }
- #endif
-
- #ifdef MDEBUG
- static void * near
- sltop(long l)
- {
- return(MK_FP(l,16));
- }
- #endif
-
- #ifdef MDEBUG
- /* Convert byte to two ascii-hex characters */
- static void near
- ctohex(char *buf,int16 c)
- {
- static char hex[] = "0123456789abcdef";
-
- *buf++ = hex[hinibble(c)];
- *buf = hex[lonibble(c)];
- }
- #endif
-
- #ifdef MDEBUG
- /* Print a buffer up to 16 bytes long in formatted hex with ascii
- * translation, e.g.,
- * 0000: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?
- */
- static void near
- fmtline(FILE *fp,int16 addr,char *buf,int16 len,int type)
- {
- char line[81], *aptr, *cptr, c;
-
- memset(line,' ',sizeof(line));
- ctohex(line,(int16)hibyte(addr));
- ctohex(line+2,(int16)lobyte(addr));
- aptr = &line[6];
- cptr = &line[55];
- while(len-- != 0){
- c = *buf++;
- ctohex(aptr,(int16)uchar(c));
- aptr += 3;
- c &= 0x7f;
- *cptr++ = isprint(uchar(c)) ? c : '.';
- }
- *cptr++ = '\0';
- if (type)
- fprintf(fp,"%s\n\r",line);
- else
- tprintf("%s\n",line);
- if (fp)
- fwrite(line,1,(unsigned)(cptr-line),fp);
- }
- #endif
-
- #ifdef __CPLUSPLUS
- static int near
- _checkok(void)
- {
- if (heapcheck() != _HEAPOK) {
- tputs("Heap doesn't check ok, trying to find failing node\n");
- return(0);
- }
- return 1;
- }
- #endif
-
- #ifdef __CPLUSPLUS
- /*-----------------------------------------------------------------------*/
- static int near
- getheap(int flag)
- {
- struct heapinfo hp;
- int i = 0;
- #ifdef MDEBUG
- int j;
- #endif
-
- hp.ptr = 0; /* start at the beginning */
- while(1) {
- if (heapwalk(&hp) == _HEAPEND)
- break;
- #ifdef MDEBUG
- if (flag == Over) {
- for (j = 0; j < hp.size/16; j += 2) {
- if (i == 0)
- tprintf("%04x ",FP_SEG(hp.ptr) + j);
- tputc(hp.in_use ? '+' : '-');
- if(++i == 72) {
- i = 0;
- tputc('\n');
- }
- }
- } else
- #endif
- if (hp.in_use == flag) {
- tprintf("%4x %5lu",FP_SEG(hp.ptr),hp.size);
- if(++i == 6) {
- i = 0;
- tputc('\n');
- } else
- tputs(" | ");
- }
- }
- tputs("\nEnd of list\n");
- return 0;
- }
- #endif
-
-
-
-
- /* ------------------------ Memory subcmds ---------------------------- */
-
-
-
-
-
- #ifdef MDEBUG
-
- static char far *DumpAddr = NULL; /* Memory dump pointer */
-
- /* called from config.c */
- int
- domdump(int argc,char *argv[],void *p)
- {
- unsigned int i;
- char *addr;
- unsigned int len = 8*16 ; /* default is 8 lines of hex dump*/
- /*
- Id *id;
- Hd *hd;
- */
- int seg;
-
- if((argc > 3 && DumpAddr == NULL) || (argc < 2 && DumpAddr == 0)) {
- tputs("Usage: dump <segment|.> [decimal range]\n");
- return 0;
- }
- if(argv[1][0] == '.' || argc == 1)
- addr = DumpAddr; /* Use last end address */
- else
- addr = (char *)(sltop(htol(argv[1])))-16; /* get address of item being dumped */
-
- seg = FP_SEG(addr);
-
- if(argc == 3) {
- len = atoi(argv[2]);
- len = ((len + 15) >> 4) << 4; /* round up to modulo 16 */
- }
-
- if(len < 1) len = 1;
- if(len > 256) len = 256;
-
- tprintf("Main Memory Dump Of Location %Fp\n"
- "Addr (offset) Hexadecimal Ascii\n",
- addr);
-
- for(i = 0; i < len; i += 16)
- fmtline((FILE *)0,seg++, (char *)(addr+i),16,0);
- DumpAddr = MK_FP(seg,0); /* update address */
- return 0;
- }
- #endif
-
- static int
- docoldst(int argc,char *argv[],void *p)
- {
- return setbool(&Memcold,"Reboot",argc,argv);
- }
-
- #ifdef __CPLUSPLUS
- /*----------------------------------------------------------------------*
- * Print heap free list *
- *-----------------------------------------------------------------------*/
- static int
- dofreelist(int argc,char *argv[],void *p)
- {
-
- if (!_checkok())
- return -1;
-
- return (getheap(Free));
- }
- #endif
-
- static int
- doibufsize(int argc,char *argv[],void *p)
- {
- return setuns(&Ibufsize,"Int buffer size",argc,argv);
- }
-
- static int
- donibufs(int argc,char *argv[],void *p)
- {
- return setint(&Nibufs,"Int pool buffers",argc,argv);
- }
-
- #if((defined __CPLUSPLUS) && defined(MDDEBUG))
- static int
- doOverview(int argc,char *argv[],void *envp)
- {
- if (!_checkok())
- return -1;
-
- return (getheap(Over));
- }
- #endif
-
- #ifdef MDEBUG
- static int
- dorecord(int argc,char **argv,void *p)
- {
-
- if (argc < 2) {
- tprintf("Memory recording %s\n", rfp ? "on" : "off");
- return(0);
- }
-
- if (!stricmp(argv[1],"off")) {
- if (rflag) {
- fclose(rfp);
- rflag=0;
- }
- return(0);
- }
-
- if (rfp) {
- fclose (rfp);
- rflag=0;
- }
- openmemrec(argv[1]);
- return(0);
- }
- #endif
-
- #ifdef MDEBUG
- static int
- dosizes(int argc,char *argv[],void *p)
- {
- int i;
-
- for(i = 0; i < 16; i += 4) {
- tprintf("N>=%5u:%7ld| N>=%5u:%7ld| N>=%5u:%7ld| N>=%5u:%7ld\n",
- 1<<i,Sizes[i], 2<<i,Sizes[i+1],
- 4<<i,Sizes[i+2],8<<i,Sizes[i+3]);
- }
- return 0;
- }
- #endif
-
- #ifdef MDEBUG
- static int
- dosnap(int argc,char **argv,void *p)
- {
- Hd cret;
-
- memset(&cret,0,sizeof(Hd));
- strcpy(cret.file,"SnapDump");
- if (!dump(&cret))
- tputs("Dump successfully written...\n");
- else
- tputs("Can't open Dumpfile...\n");
- return 0;
- }
- #endif
-
- /*----------------------------------------------------------------------*
- * Print heap stats *
- *-----------------------------------------------------------------------*/
- static int
- dostat(int argc,char *argv[],void *envp)
- {
- extern int Intqlen, Iminfree;
- extern unsigned Ibufsize;
- extern long Ibuffail;
-
- tprintf("coreleft %lu",availmem());
- tprintf("\nallocs %lu frees %lu diff %lu invalid allocs %lu frees %lu corrupted %lu\n",
- Allocs,Frees,Allocs-Frees,Memfail,Invalid,Overuse);
- tprintf("int-off calls to malloc %lu free %lu\n"
- "Intqlen %u Ibufsize %u Iminfree %u Ibuffail %lu\n",
- Intalloc,Intfree,Intqlen,Ibufsize,Iminfree,Ibuffail);
- return 0;
- }
-
- static int
- dothresh(int argc,char *argv[],void *p)
- {
- return setlong(&Memthresh,"Mem threshold (bytes)",argc,argv);
- }
-
- #if((defined __CPLUSPLUS) && defined(MDDEBUG))
- /*----------------------------------------------------------------------*
- * Print heap used list *
- *-----------------------------------------------------------------------*/
- static int
- dousedlist(int argc,char *argv[],void *p)
- {
- if (!_checkok())
- return -1;
-
- return (getheap(Used));
- }
-
- #endif
-
- extern int dorefiq __ARGS((int argc,char *argv[],void *p));
-
- /* ------------------------ Memory subcmd-parser ------------------------- */
- int
- domem(int argc,char *argv[],void *p)
- {
- struct cmds Memcmds[] = {
- #ifdef __CPLUSPLUS
- "freelist", dofreelist, 0, 0, NULLCHAR,
- #endif
- "ibufsize", doibufsize, 0, 0, NULLCHAR,
- "nibufs", donibufs, 0, 0, NULLCHAR,
- #if((defined __CPLUSPLUS) && defined(MDDEBUG))
- "overview", doOverview, 0, 0, NULLCHAR,
- #endif
- "reboot", docoldst, 0, 0, NULLCHAR,
- #ifdef MDEBUG
- "record", dorecord, 0, 0, NULLCHAR,
- #endif
- "refiq", dorefiq, 0, 0, NULLCHAR,
- #ifdef MDEBUG
- "sizes", dosizes, 0, 0, NULLCHAR,
- "snap", dosnap, 0, 2, "snap start",
- #endif
- "status", dostat, 0, 0, NULLCHAR,
- "thresh", dothresh, 0, 0, NULLCHAR,
- #if((defined __CPLUSPLUS) && defined(MDDEBUG))
- "usedlist", dousedlist, 0, 0, NULLCHAR,
- #endif
- NULLCHAR,
- };
-
- return subcmd(Memcmds,argc,argv,p);
- }
-
-
-
-